/**
 * @file Parameter.h
 * @author enemy1205 (enemy1205@qq.com)
 * @brief 参数头文件
 * @date 2021-08-16
 *
 */
#pragma once

#include <iostream>
#include <string>
#include <opencv2/core/types.hpp>
#include <opencv2/core/persistence.hpp>
#include <deque>
#include <vector>

using std::string;
using std::vector;
using std::deque;

struct LightBlobParam {
    //Filter lights
    float min_area;
    float light_min_length;
    float far_max_length;
    float far_min_ratio;
    float far_max_ratio;
    float light_min_area;
    float light_max_ratio;
    float light_min_area_ratio;
//    float light_max_area_ratio;
    float light_max_angle;
    float ERR_AREA_RATIO;   //面积比误差权重
    float ERR_ANGLE;        //角度误差权重

    explicit LightBlobParam(const string &path);
};

const LightBlobParam L_param("../Parameter/para/LightBlob.yml");

struct ArmorParam {

    //Pre-treatment
    int threshold;

    //Filter pairs
    float light_max_angle_diff;
    float light_max_height_ratio;
    float light_max_width_ratio;
    float max_up_down_dis_ratio;

    //Filter armor
    float BIG_armor_min_ratio;
    float BIG_armor_max_ratio;
    float armor_min_ratio;
    float armor_max_ratio;//装甲板长宽比
    float armor_max_angle;//装甲板与水平最大夹角
    float max_dig_width_ratio;//对角线与宽之比
    float min_dig_width_ratio;
    float ERROR_ANGLE_DIFF; //灯条角度差误差权重
    float ERROR_ANGLE;      //角度误差权重
    float ERROR_H_W_RATIO;   //高宽比误差权重
    float ERROR_WH_RATIO;   //装甲板宽高比误差权重
    float ERROR_DIG_WIDTH;  //装甲板对角线宽度比误差权重

    //Match tracker
    float MAX_DELTA_DIS;    //相邻两帧允许最大位置变化
    float MAX_DELTA_DIS_RATIO;//最大允许与上帧位置变化比
    float MAX_DIRECTION_RATIO;//最大允许与上帧水平位置变化比
    //other params
    const vector<cv::Point3f> Small_Armor = {{-65.5, 26.5,  7},
                                             {-65.5, -26.5, -7},
                                             {65.5,  -26.5, -7},
                                             {65.5,  26.5,  7}};
    const vector<cv::Point3f> Big_Armor = {{-113, 26.5,  7},
                                           {-113, -26.5, -7},
                                           {113,  -26.5, -7},
                                           {113,  26.5,  7}};
    float extend_k;//获取整个装甲板的延伸系数
    int Seq_maxlength;//装甲板队列储存最大长度
    float predictConfidence;//预测置信度
    explicit ArmorParam(const string &);
};

const ArmorParam A_param("../Parameter/para/Armor.yml");

struct RuneParam {
    //Pre-treatment
    int threshold;
    int ksize;
    //Rune_size
    int R_minarea;
    int R_maxarea;//每次击打能量机关均在固定位置,maxarea可适当给予限制
    float Max_Rune_center_ratio;
    float Min_Rune_center_ratio;
    //Rune_Armor_size
    float min_lw_ratio;
    float max_lw_ratio;
    // ------【神符轮廓世界坐标】------
    const vector<cv::Point3f> wRUNE_CONTOUR = {{-113, 70,  0},
                                               {-113, -70, 0},
                                               {113,  -70, 0},
                                               {113,  70,  0},
                                               {0,    700, 0}};;
    //other params
    int RECORD_FRAMES;//记录帧数
    float MAX_DELTA_ANGLE;//最大差异角
    explicit RuneParam(const string &);
};

const RuneParam R_param("../Parameter/para/Rune.yml");

struct CameraParam {
    explicit CameraParam(const string &);

    cv::Mat cameraMatrix;
    cv::Mat distCoeff;
    int cam_exposure;
    int cam_contrast;
    int cam_gamma;
    int cam_Bgain;
    int cam_Ggain;
    int cam_Rgain;
};

const CameraParam cameraParam("../Parameter/para/CameraParam.yml");

struct KalmanFilterParam {
    explicit KalmanFilterParam(const string &);

    float GYRO_PROCESS_ERROR;   // Armor - 普通模式过程噪声协方差系数
    float GYRO_MEASURE_ERROR;   // Armor - 普通模式测量噪声协方差系数
    float DIS_PROCESS_ERROR;   // Armor - 距离过程噪声协方差系数
    float DIS_MEASURE_ERROR;   // Armor - 距离测量噪声协方差系数
    float ANGLE_PROCESS_ERROR; // Rune - 角度过程噪声协方差系数
    float ANGLE_MEASURE_ERROR; // Rune - 角度测量噪声协方差系数
};

const KalmanFilterParam kalmanFilterParam("../Parameter/para/KalmanParam.yml");

struct StrategyParam {
    StrategyParam(const string &);

    int SENTRY_TRACK_FRAMES;      // Armor - 哨兵模式追踪帧数
    int NORMAL_TRACK_FRAMES;      // Armor - 普通模式
    int RECORD_FRAMES;            // Armor - 时间序列记录最大帧数
    int MAX_DIS;                  // Armor - 最远距离
    int MAX_DIS_DIFF;             // Armor - 最大切换装甲板距离差值
    float GYRO_RADIUS_RATIO;      // 击打小陀螺时射击半径比值
    float NORMAL_RADIUS_RATIO;    // 普通模式时射击半径比值
    float SHOOT_CONFIDENCE_LEVEL; // 普通模式下预测点的置信度
    int SHOOT_SPEED_15_BIAS;      // 15m/s 弹速负偏置
    int SHOOT_SPEED_18_BIAS;      // 18m/s 弹速负偏置
    int SHOOT_SPEED_30_BIAS;      // 30m/s 弹速负偏置
};

const StrategyParam strategyParam("../Parameter/para/StrategyParam.yml");

struct CompensateParam {
    int ITERATE_TIMES;           // 迭代次数
    float ITERATE_ACCURACY;      // 迭代精度
    float YAW_COMPENSATE;        // yaw 额定补偿
    float RUNE_PITCH_COMPENSATE; // 打符 pitch 额定补偿
    float PITCH_COMPENSATE;      // pitch 额定补偿
    float WINDAGE_TIME_COMPENSATE;//风阻时间补偿
    explicit CompensateParam(const string &param);
};

const CompensateParam compensateParam("../Parameter/para/CompensateParam.yml");

struct OtherParam {
    explicit OtherParam(const string &);

    uint8_t Time_per_frame;//每帧耗时(画面调试用)
    u_char init_detect_mode;// 识别模式
    uint8_t init_color_mode;//己方颜色
    float init_pitch;
    float init_yaw;
    float init_pitch_speed;
    float init_yaw_speed;
    int init_shoot_speed;
    float fly_time;//飞行时间
};

const OtherParam Other_param("../Parameter/para/OtherParam.yml");